//
// Created by shanshi on 2025/6/9.
//

#ifndef HASHLRU_H
#define HASHLRU_H
#include <thread>
#include <cmath>
#include <string.h>
#include <vector>

#include "LRU.h"

/**
 * @file HashLRU.h
 * @author luxiaolu
 * @brief
 * @version 0.1
 * @date 2025-05-18
 * 缺点：访问模式不敏感，A-B-C-D-A
 * 缓存污染：加载不再使用的内容
 * 不适用场景
 * 锁的粒度大：多线程高并发，同步等待时间开销大 解决方案：将lru分片
 * @copyright Copyright (c) 2025
 */

template<typename Key, typename Value>
class KHashLRUCaches {
public:
    /*
    *这段代码是构造函数初始化列表的一部分，功能如下：
    如果 `sliceNum > 0`，则使用传入的 `sliceNum` 值初始化 `sliceNum_`；
    否则（即 `sliceNum <= 0`），则使用 `std::thread::hardware_concurrency() 硬件支持的线程数` 的返回值作为默认值初始化 `sliceNum_`，表示根据 CPU 核心数自动选择线程数量。
     **/
    KHashLRUCaches(size_t capacity, int sliceNum)
        : capacity_(capacity)
        , sliceNum_(sliceNum > 0 ? sliceNum : std::thread::hardware_concurrency()) {
        size_t sliceSize = std::ceil(capacity_ / static_cast<double>(sliceNum_));
        for (int i = 0; i < sliceNum_; ++i) {
            lru_slice_caches_vector_.emplace_back(new KLruCache<Key, Value>(sliceSize));
        }
    }
    void put(Key key, Value value) {
        size_t sliceIndex = Hash(key) % sliceNum_;
        return lru_slice_caches_vector_[sliceIndex]->put(key, value);
    }
    bool get(Key key, Value &value) {
        size_t sliceIndex = Hash(key) % sliceNum_;
        return lru_slice_caches_vector_[sliceIndex]->get(key, value);
    }
    bool get(Key key) {
        Value value;
        memset(&value, 0, sizeof(value));
        get(key, value);
        return value;
    }
private:
    size_t  capacity_;
    int     sliceNum_;
    std::pmr::vector<std::unique_ptr<KLruCache<Key, Value>>> lru_slice_caches_vector_;
};

#endif //HASHLRU_H
